<?php
if (!defined('CORE_PATH'))
    die('Access Denied');

kan_import('adjacency.class'); // import the Adjacency List Management Class

class PageManager extends Manager {

	protected $models = array('Page');
	
    /**
     *
     * @var adjacencyTree
     */
    private $tree = NULL;

    public function __construct() {
        parent::__construct('pages');
        $this->setItemClassName('Page');

        $this->tree = new adjacencyTree();
        $this->tree->setdbtable( $this->Page->getTableName() );
        $this->tree->setidfield("id");
        $this->tree->setparentidfield("ParentID");
        $this->tree->setpositionfield("PagePosition");
        $this->tree->setLevelField("PageLevel");
        $this->tree->setWhereClause("WHERE SiteID = " . SITE_ID);
        $this->tree->setDBConnectionID($this->getDatabase()->getConnection());
    }

    /**
     *
     * @return adjacencyTree
     */
    public function getAdjacencyTree() {
        return $this->tree;
    }

    public function isSitePage($pageAlias, $siteid = '') {

        if ($siteid == '' && defined("SITE_ID")) {
            $siteid = SITE_ID;
        }
        
        $pages = $this->Page->count(array(
            'filter' => array(
                'OR' => array(
                    'PageNameAlias' => $pageAlias,
                    'PagePath' => $pageAlias
                ),
                'SiteID' => SITE_ID
            )
        ));
        
        return $pages > 0;
    }

    /**
     *
     * @param <type> $id
     * @return Page
     */
    public function getPage($id, $siteid = '') {

        if ($siteid == '' && defined("SITE_ID")) {
            $siteid = SITE_ID;
        }
        
        $page = $this->Page->findFirst( array(
            'filter' => array(
                'OR' => array(
                    'id' => $id,
                    'PageNameAlias' => $id,
                    'PagePath' => $id
                ),
                'SiteID' => SITE_ID
            )
        ));
        
        if( $page !=  NULL ) {
            $page->setAdjacencyTree($this->tree);
        }
        
        return $page;

        /*$db = $this->getDatabase();

        $query = sprintf("SELECT * FROM pages WHERE (id = %s OR PageNameAlias = %s OR PagePath = %s) AND SiteID = %s", $db->sanitizeInput($id, 'int'), $db->sanitizeInput($id, 'text'), $db->sanitizeInput("/" . $id, 'text'), $db->sanitizeInput($siteid, "int"));

        $data = $db->query($query, true)->getRow();

        return new Page($data, $this->tree);*/
    }

    public function getPages($params = array(), $siteid = -1) {

        if (!is_array($params)) {
            trigger_error("Parameters to the getPages function must be supplied as an array");
            return;
        }

        if ($siteid == -1 && defined("SITE_ID")) {
            $siteid = SITE_ID;
        }

        $db = $this->getDatabase();
        $level = isset($params['level']) ? $params['level'] : -1;
        $depth = isset($params['depth']) ? $params['depth'] : ($level != -1 ? $level : 10);
        $parent = isset($params['parent']) ? $params['parent'] : -1;

        if( array_key_exists('parent', $params) ) {
			$parentClause = $parent != -1 && intval($parent) > 0 ?
				sprintf(" AND ParentID = %s", $db->sanitizeInput($parent, 'int')) :
				" AND ParentID IS NULL ";
		} else {
			$parentClause = "";	
		}
        
        $conditions = array(
            'SiteID' => SITE_ID,
            "PageLevel >=" => $level,
            "PageLevel <=" => $depth
        );
        
        if( array_key_exists('parent', $params) ) {
            
            if( $parent != -1 && intval($parent) > 0 ) {
                $conditions['ParentID'] = $parent;
            }
            
            else {
                $conditions['ParentID'] = "IS NULL";
            }
        }

        $pages = $this->Page->find(array(
            'filter' => $conditions,
            'order' => array("ParentID", "PagePosition")
        ));
		
		foreach($pages as $page) {
			$page->setAdjacencyTree( $this->getAdjacencyTree() );	
		}
		
		return $pages;
    }
	
	/**
	 * Returns the URL to the view/theme loader page specified. The parameter specified
	 * should be an existing view/theme loader file, else an error will be thrown
	 *
	 * @param string $pageType
	 * @return string
	 */
    public function getPageURL($pageType = 'index') {
		
		// throw exception if $pageType is not properly specified
		if( !is_string($pageType) || trim($pageType) == '' ) {
			throw new InvalidArgumentException("The Page To Provide A Link For Was Not Specified Correctly");
		}
		
		// if an actual view file does not exist for the page, throw an error
		$file = kan_fix_path("../core/views/" . (($pageType == "home" || $pageType == "index") ? "index" : $pageType) . ".php");
		/*if( !file_exists($file) ) {
			throw new Exception("A View File Does Not Exist For The Specified Page");
		}*/
		
		// if all is well build the url and present it
        $url = "../pages/" . ( ($pageType == "home" || $pageType == "index") ? "index" : $pageType) . ".php?siteid=" . $this->getSiteIdentifier();

		// if using SEF_URLS
        if (SEF_URLS) {
            $url = "../" . $this->getSiteIdentifier() . "/" . (($pageType == "home" || $pageType == "index") ? "" : $pageType);
        }
		
		// if in the CMS do not fix the URL, return as is
		if( defined("IN_CMS") && IN_CMS ) {
			return $url;	
		}

        return kan_fix_url($url);
    }

    /**
     *
     * @return Page
     */
    public function createPage() {
        $db = $this->getDatabase();

        $pagePath = "/";
        $pageLevel = 1;

        // if a parent page has been specified, build the path based on that
        if (isset($_POST['ParentID']) && $_POST['ParentID'] != '') {
            $parentPage = $this->getPage($_POST['ParentID']);
            $pagePath = $parentPage->getPath() . "/";

            // update the page level
            $pageLevel = $parentPage->getLevel() + 1;
        }

        // complete path
        $pagePath .= $_POST['PageNameAlias'];
        
        $page = new Page( array(
            'SiteID' => SITE_ID,
            'ParentID' => $_POST['ParentID'],
            'PageName' => $_POST['PageName'],
			'PageNameAlias' => $_POST['PageNameAlias'],
            'PagePosition' => $_POST['PagePosition'],
            'PageLevel' => $pageLevel,
            'PageDescription' => $_POST['PageDescription'],
            'PageSummary' => $_POST['PageSummary'],
            'PagePath' => $pagePath,
            'PageContentType' => $_POST['PageContentType'],
            'PageContent' => $_POST['PageContent'],
            'PageLayout' => $_POST['PageLayout'],
            'RedirectURL' => $_POST['RedirectURL'],
            'Published' => 0
        ));
        
        $page->save();
        
        return $page;
    }

    /**
     *
     * @return <type>
     */
    public function updatePage() {
        $db = $this->getDatabase();

        $pagePath = "/";
        $pageLevel = 1;

        // if a parent page has been specified, build the path based on that
        if (isset($_POST['ParentID']) && $_POST['ParentID'] != '') {
            $parentPage = $this->getPage($_POST['ParentID']);
            $pagePath = $parentPage->getPath() . "/";

            // update the page level incase the parent page has changed
            $pageLevel = $parentPage->getLevel() + 1;
        }

        // complete path
        $pagePath .= $_POST['PageNameAlias'];
        
        $page = new Page( array(
            'id' => $_POST['id'],
            'ParentID' => $_POST['ParentID'],
            'PageName' => $_POST['PageName'],
			'PageNameAlias' => $_POST['PageNameAlias'],
            'PagePosition' => $_POST['PagePosition'],
            'PageLevel' => $pageLevel,
            'PageDescription' => $_POST['PageDescription'],
            'PageSummary' => $_POST['PageSummary'],
            'PagePath' => $pagePath,
            'PageContentType' => $_POST['PageContentType'],
            'PageContent' => $_POST['PageContent'],
            'PageLayout' => $_POST['PageLayout'],
            'RedirectURL' => $_POST['RedirectURL']
        ));
        
        $page->save();
        
        return $page;
    }

    /**
     * @param array $ids
     */
    public function deletePages($ids) {
        if (!is_array($ids)) {
            return;
        }
        
        $this->Page->deleteAll( array('id IN' => $ids));
    }

    public function listPages($options = NULL) {


        $default = array(
            "id" => 'nav',
            "class" => 'menu',
            "depth" => 10,
            "includeHome" => true,
            "startDepth" => 1
        );

        if ($options == NULL) {
            $options = array();
        }

        $options = array_merge($default, $options);

        $nodes = $this->getAdjacencyTree()->getFullNodes(
                array("id", "SiteID", "PageName", "PageNameAlias", "PageType", "PagePath", "RedirectURL", "Published")
        );

        echo "<ul class='{$options['class']}' id='{$options['id']}'>";

        if ($options['includeHome']) {
            $isCurrent = $_SERVER['REQUEST_URI'] == kan_site_home() ? 'class="current"' : "";

            echo "<li $isCurrent><a id='home-link' href='" . kan_site_home() . "' >Home</a></li>";
        }

        $this->printPageList($nodes, $options['depth'], $options['startDepth']);
        echo "</ul>";
    }

    public function getPagesAsHTMLList($class = 'nav', $depth = 10, $includeHome = true, $startDepth = 1) {

        $nodes = $this->getAdjacencyTree()->getFullNodes(
                array("id", "SiteID", "PageName", "PageNameAlias", "PageType", "PagePath", "RedirectURL", "Published")
        );

        echo "<ul class='$class'>";

        if ($includeHome) {
            $isCurrent = $_SERVER['REQUEST_URI'] == kan_site_home() ? 'class="current"' : "";

            echo "<li $isCurrent><a id='home-link' href='" . kan_site_home() . "' >Home</a></li>";
        }

        $this->printPageList($nodes, $depth, $startDepth);
        echo "</ul>";
    }

    private function printPageList($page_data, $depth, $startDepth) {
        $currentDepth = $startDepth;
        $thisDepth = $startDepth;

        foreach ($page_data as $data) {
            $page = new Page($data);
            $current = stristr($_SERVER['REQUEST_URI'], $page->getURL()) || stristr($_SERVER['REQUEST_URI'], $page->getRedirectURL()) ? 'class="current"' : "";

            if (!$page->isPublished()) {
                continue;
            }
            ?>

            <li id="page-li-<?php echo $page->getId(); ?>" <?php echo $current; ?> >
                <a id="<?php echo $page->getId(); ?>" data-id="<?php echo $page->getId(); ?>" href='<?php echo $page->getURL(); ?>' ><?php echo $page->getName(); ?></a><?php
				if (isset($data['children']) && $currentDepth < $depth) {
					echo "<ul>";
					$this->printPageList($data['children'], $depth, ++$currentDepth);
					echo "</ul>";
				}
            ?>

            </li><?php
            $currentDepth = $thisDepth;
        }
    }

    /**
     * Renders the controller information via a PageView object
     */
    public function render() {
        $this->view = new PageView($this);
        parent::render();
    }

}
?>